package org.judo.components.state;

import java.util.HashMap;
import java.util.Iterator;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.judo.components.ComponentManager;
import org.judo.components.JudoComponent;

public class ComponentPersistence
{
	private static HashMap statefulComponents = new HashMap();
	private static HashMap statefulComponentGroups = new HashMap();
	
	public static ComponentPersistence getInstance(HttpSession session)
	{
		ComponentPersistence cp = null;
		
		cp = (ComponentPersistence)
			session.getAttribute("__componentPersistence");
		
		if (cp == null)
		{
			cp = new ComponentPersistence();
			session.setAttribute("__componentPersistence",cp);
		}
		
		return cp;
	}
	
	/**
	 * Session Scoped Components
	 */
	public JudoComponent getStatefulComponent(Class type,HashMap connections) 
		throws Exception
	{
		JudoComponent component = null;
		
		component = getComponentFromPersistentStore(
				type,statefulComponents,connections);
		
		return component;
	}
	
	/**
	 * Grouped Scoped Components
	 */
	public JudoComponent getGroupComponent(
			Class type,String groupName, HashMap connections) 
		throws Exception
	{
		JudoComponent component = null;
		HashMap group = getGroup(groupName);
		component = getComponentFromPersistentStore(type,group,connections);
		
		return component;
	}
	
	private JudoComponent getComponentFromPersistentStore(
			Class type, HashMap store, HashMap connections) 
		throws Exception
	{
		JudoComponent component = (JudoComponent)
			store.get(type.getCanonicalName());
		
		if (component == null)
		{
			component = ComponentManager.createNewComponent(type,connections);
			store.put(type.getCanonicalName(),component);
		}
		
		return component;
	}
	
	protected HashMap getGroup(String groupName)
	{
		HashMap group = (HashMap)
			statefulComponentGroups.get(groupName);
	
		if (group == null)
		{
			group = new HashMap();
			statefulComponentGroups.put(groupName,group);
		}
		
		return group;
	}
	
	public void invalidateStatefulComponent(Class type)
	{
		statefulComponents.remove(type.getCanonicalName());
	}
	
	public void invalidateGroupComponent(String groupName,Class type)
	{
		HashMap group = getGroup(groupName);
		group.remove(type.getCanonicalName());
	}
	
	public Iterator getAllGroupNames()
	{
		return statefulComponentGroups.keySet().iterator();
	}
	
	public HashMap getGroupComponents(String name)
	{
		return (HashMap)statefulComponentGroups.get(name);
	}
	
	public Iterator getStatefulNames()
	{
		return statefulComponents.keySet().iterator();
	}
	
	public JudoComponent getComponentObject(String name)
	{
		return (JudoComponent)statefulComponents.get(name);
	}
}
